#include "stdafx.h"
#include "MainDlg.h"
#include "ComFunPathHelper.h"

static int CALLBACK CompareFunc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
{
	CListViewCtrl  *pList=(CListViewCtrl *)lParamSort; 
	CString strItem1;
	pList->GetItemText(lParam1, 1, strItem1.GetBuffer(MAX_PATH), MAX_PATH);
	strItem1.ReleaseBuffer();
	CString strItem2;
	pList->GetItemText(lParam2, 1, strItem2.GetBuffer(MAX_PATH), MAX_PATH);
	strItem2.ReleaseBuffer();

	int nItem1 = 99999999;
	if (!strItem1.IsEmpty())
	{
		nItem1 = _tstoi((LPCTSTR)strItem1+_tcslen(_T("File")));
	}

	int nItem2 = 99999999;
	if (!strItem2.IsEmpty())
	{
		nItem2 = _tstoi((LPCTSTR)strItem2+_tcslen(_T("File")));
	}

	if (nItem1 > nItem2)
	{
		return 1;
	}
	else if (nItem1 == nItem2)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}

void CMainDlg::InitList()
{
	m_lstCurretnUsed.Attach(GetDlgItem(IDC_LIST_CURRENT));
	m_lstCurretnUsed.ModifyStyle(0, LVS_SHOWSELALWAYS);
	DWORD dwType = ListView_GetExtendedListViewStyle(m_lstCurretnUsed);
	ListView_SetExtendedListViewStyle(m_lstCurretnUsed, dwType | LVS_EX_FULLROWSELECT);

	m_lstStored.Attach(::GetDlgItem(m_hWnd, IDC_LIST_MANAGENT));
	m_lstStored.ModifyStyle(0, LVS_SHOWSELALWAYS);
	dwType = ListView_GetExtendedListViewStyle(m_lstStored);
	ListView_SetExtendedListViewStyle(m_lstStored, dwType | LVS_EX_FULLROWSELECT);

	m_lstCurretnUsed.InsertColumn(0, L"Num.", LVCFMT_LEFT, 40);
	m_lstCurretnUsed.InsertColumn(1, L"Name", LVCFMT_LEFT, 100);
	m_lstCurretnUsed.InsertColumn(2, L"Path", LVCFMT_LEFT, 250);

	m_lstStored.InsertColumn(0, L"Num.", LVCFMT_LEFT, 40);
	m_lstStored.InsertColumn(1, L"Path", LVCFMT_LEFT, 300);
}

void CMainDlg::LoadCurrentUesdProject(std::map<CString, CString>& mapCurrentUserProject)
{
	mapCurrentUserProject.clear();
	CComFunRestry::QueryKey(HKEY_CURRENT_USER,
		L"Software\\Microsoft\\VisualStudio\\9.0\\ProjectMRUList", mapCurrentUserProject);
}

void CMainDlg::FillCurrentUsedProjectList()
{
	std::map<CString, CString> mapCurrentUserProject;
	LoadCurrentUesdProject(mapCurrentUserProject);
	std::map<CString, CString>::iterator it = mapCurrentUserProject.begin();

	DWORD dwCount = 0;
	for (; it != mapCurrentUserProject.end(); it++)
	{
		CString strNo;
		int nCount = m_lstCurretnUsed.GetItemCount();
		strNo.Format(_T("%d"), nCount+1);
		m_lstCurretnUsed.InsertItem(nCount, strNo);

		m_lstCurretnUsed.SetItemText(nCount, 1, it->first);
		m_lstCurretnUsed.SetItemText(nCount, 2, it->second);
	}
	RefreshCurrentList(FALSE);
}

void CMainDlg::RefreshCurrentList(BOOL bRefreshFileName, BOOL bSort)
{
	if (!bRefreshFileName)
	{
		if (bSort)
		{
			for(int i = 0; i < m_lstCurretnUsed.GetItemCount(); i++)
			{
				m_lstCurretnUsed.SetItemData(i, i);
			}

			m_lstCurretnUsed.SortItems(CompareFunc, (LPARAM)&m_lstCurretnUsed);
		}
		int nCount = m_lstCurretnUsed.GetItemCount();
		for (int i = 0; i < nCount; i++)
		{
			TCHAR strNum[5] = {};
			_itot_s(i + 1, strNum, 5, 10);
			m_lstCurretnUsed.SetItemText(i, 0, strNum);
		}
	}
	else
	{
		if (bSort)
		{
			for(int i = 0; i < m_lstCurretnUsed.GetItemCount(); i++)
			{
				m_lstCurretnUsed.SetItemData(i, i);
			}

			m_lstCurretnUsed.SortItems(CompareFunc, (LPARAM)&m_lstCurretnUsed);
		}
		int nCount = m_lstCurretnUsed.GetItemCount();
		for (int i = 0; i < nCount; i++)
		{
			TCHAR strNum[5] = {};
			_itot_s(i + 1, strNum, 5, 10);
			CString strNumFileMame(_T("File"));
			strNumFileMame += strNum;
			m_lstCurretnUsed.SetItemText(i, 0, strNum);
			m_lstCurretnUsed.SetItemText(i, 1, strNumFileMame);
		}
	}
}

void CMainDlg::RefreshStoredList()
{
	for(int i = 0; i < m_lstStored.GetItemCount(); i++)
	{
		m_lstStored.SetItemData(i, i);
	}

	int nCount = m_lstStored.GetItemCount();
	for (int i = 0; i < nCount; i++)
	{
		TCHAR strNum[5] = {};
		_itot_s(i + 1, strNum, 5, 10);
		m_lstStored.SetItemText(i, 0, strNum);
	}
}

void CMainDlg::LoadStoredProject()
{
	CString strPath;
	GetStoredConfigpath(strPath);

	int nItemCount = ::GetPrivateProfileInt(_T("Globe"), _T("TotalCount"), 0, strPath);

	for (int i = 0; i < nItemCount; i++)
	{
		TCHAR strIndex[10] = {};
		_itot_s(i, strIndex, 10, 10);

		CString strSolutionPath;
		::GetPrivateProfileString(_T("Globe"), strIndex, _T(""),
			strSolutionPath.GetBuffer(MAX_PATH), MAX_PATH, strPath);
		strSolutionPath.ReleaseBuffer();

		//m_lstStored.SetItemText(i, 1, strSolutionPath.GetBuffer(MAX_PATH), MAX_PATH);
		m_lstStored.InsertItem(i, strIndex+1);
		m_lstStored.SetItemText(i, 1, strSolutionPath);
	}

	RefreshStoredList();
}

void CMainDlg::FillStoredProjectList()
{

}

LRESULT CMainDlg::OnInitDialog( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ )
{
	// center the dialog on the screen
	CenterWindow();

	// set icons
	HICON hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
		IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
	SetIcon(hIcon, TRUE);
	HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
		IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
	SetIcon(hIconSmall, FALSE);

	InitList();
	FillCurrentUsedProjectList();
	LoadStoredProject();
	return TRUE;
}

LRESULT CMainDlg::OnCancel( WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/ )
{
	EndDialog(wID);
	return 0;
}

LRESULT CMainDlg::OnBnClickedButtonStored(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	//Get current selected item index and its data
	int nCurrentSleect = m_lstCurretnUsed.GetSelectedIndex();
	if (-1 == nCurrentSleect)
	{
		return -1;
	}

	CString strProjectPath;
	m_lstCurretnUsed.GetItemText(nCurrentSleect, 2, strProjectPath.GetBuffer(MAX_PATH), MAX_PATH);
	strProjectPath.ReleaseBuffer();

	//remove it and select a new one
	m_lstCurretnUsed.DeleteItem(nCurrentSleect);
	int nNewSelect = nCurrentSleect > m_lstCurretnUsed.GetItemCount() - 1 ?
		m_lstCurretnUsed.GetItemCount() - 1 : nCurrentSleect;
	BOOL bSelect = m_lstCurretnUsed.SelectItem(nNewSelect);

	//add new to the stored list
	CString strNum;
	strNum.Format(_T("%d"), m_lstStored.GetItemCount());
	m_lstStored.InsertItem(m_lstStored.GetItemCount(), strNum);
	m_lstStored.SetItemText(m_lstStored.GetItemCount() - 1, 1, strProjectPath);
	m_lstStored.SelectItem(m_lstStored.GetItemCount() - 1);

	RefreshCurrentList(TRUE);
	RefreshStoredList();
	return 0;
}

LRESULT CMainDlg::OnBnClickedButtonAddNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	//Get current selected item index and its data
	int nCurrentSleect = m_lstStored.GetSelectedIndex();
	if (-1 == nCurrentSleect)
	{
		return -1;
	}

	CString strProjectPath;
	m_lstStored.GetItemText(nCurrentSleect, 1, strProjectPath.GetBuffer(MAX_PATH), MAX_PATH);
	strProjectPath.ReleaseBuffer();

	//remove it and select a new one
	m_lstStored.DeleteItem(nCurrentSleect);
	int nNewSelect = nCurrentSleect > m_lstStored.GetItemCount() - 1 ?
		m_lstStored.GetItemCount() - 1 : nCurrentSleect;
	BOOL bSelect = m_lstStored.SelectItem(nNewSelect);

	//add new to the current list
	CString strNum;
	strNum.Format(_T("%d"), m_lstCurretnUsed.GetItemCount());
	m_lstCurretnUsed.InsertItem(m_lstCurretnUsed.GetItemCount(), strNum);
	m_lstCurretnUsed.SetItemText(m_lstCurretnUsed.GetItemCount() - 1, 2, strProjectPath);
	m_lstCurretnUsed.SelectItem(m_lstCurretnUsed.GetItemCount() - 1);

	RefreshCurrentList(TRUE);
	RefreshStoredList();
	return 0;
}

LRESULT CMainDlg::OnBnClickedButtonUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	int nCurrentSleect = m_lstCurretnUsed.GetSelectedIndex();
	if (-1 == nCurrentSleect || 0 == nCurrentSleect)
	{
		return 0;
	}

	CString strFileNamePri;
	CString strFilePathPri;
	m_lstCurretnUsed.GetItemText(nCurrentSleect - 1, 1, strFileNamePri.GetBuffer(MAX_PATH), MAX_PATH);
	strFileNamePri.ReleaseBuffer();
	m_lstCurretnUsed.GetItemText(nCurrentSleect - 1, 2, strFilePathPri.GetBuffer(MAX_PATH), MAX_PATH);
	strFilePathPri.ReleaseBuffer();

	CString strFileNameCurrent;
	CString strFilePathCurrent;
	m_lstCurretnUsed.GetItemText(nCurrentSleect, 1, strFileNameCurrent.GetBuffer(MAX_PATH), MAX_PATH);
	strFileNameCurrent.ReleaseBuffer();
	m_lstCurretnUsed.GetItemText(nCurrentSleect, 2, strFilePathCurrent.GetBuffer(MAX_PATH), MAX_PATH);
	strFilePathCurrent.ReleaseBuffer();

	m_lstCurretnUsed.SetItemText(nCurrentSleect - 1, 1, strFileNameCurrent);
	m_lstCurretnUsed.SetItemText(nCurrentSleect - 1, 2, strFilePathCurrent);

	m_lstCurretnUsed.SetItemText(nCurrentSleect, 1, strFileNamePri);
	m_lstCurretnUsed.SetItemText(nCurrentSleect, 2, strFilePathPri);
	m_lstCurretnUsed.SelectItem(nCurrentSleect - 1);

	RefreshCurrentList(TRUE, FALSE);
	return 0;
}

LRESULT CMainDlg::OnBnClickedButtonDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	int nCurrentSleect = m_lstCurretnUsed.GetSelectedIndex();
	if (-1 == nCurrentSleect || m_lstCurretnUsed.GetItemCount() - 1 == nCurrentSleect)
	{
		return 0;
	}

	CString strFileNameNext;
	CString strFilePathNext;
	m_lstCurretnUsed.GetItemText(nCurrentSleect + 1, 1, strFileNameNext.GetBuffer(MAX_PATH), MAX_PATH);
	strFileNameNext.ReleaseBuffer();
	m_lstCurretnUsed.GetItemText(nCurrentSleect + 1, 2, strFilePathNext.GetBuffer(MAX_PATH), MAX_PATH);
	strFilePathNext.ReleaseBuffer();

	CString strFileNameCurrent;
	CString strFilePathCurrent;
	m_lstCurretnUsed.GetItemText(nCurrentSleect, 1, strFileNameCurrent.GetBuffer(MAX_PATH), MAX_PATH);
	strFileNameCurrent.ReleaseBuffer();
	m_lstCurretnUsed.GetItemText(nCurrentSleect, 2, strFilePathCurrent.GetBuffer(MAX_PATH), MAX_PATH);
	strFilePathCurrent.ReleaseBuffer();

	m_lstCurretnUsed.SetItemText(nCurrentSleect + 1, 1, strFileNameCurrent);
	m_lstCurretnUsed.SetItemText(nCurrentSleect + 1, 2, strFilePathCurrent);
	m_lstCurretnUsed.SetItemText(nCurrentSleect, 1, strFileNameNext);
	m_lstCurretnUsed.SetItemText(nCurrentSleect, 2, strFilePathNext);
	m_lstCurretnUsed.SelectItem(nCurrentSleect + 1);

	RefreshCurrentList(TRUE, FALSE);
	return 0;
}

LRESULT CMainDlg::OnBnClickedButtonSave(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	CComFunRestry::Removekey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\VisualStudio\\9.0\\ProjectMRUList"));
	CComFunRestry::Createkey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\VisualStudio\\9.0"), _T("ProjectMRUList"));
	for (int i = 0; i < m_lstCurretnUsed.GetItemCount(); i++)
	{
		CString strName;
		m_lstCurretnUsed.GetItemText(i, 1, strName.GetBuffer(MAX_PATH), MAX_PATH);
		strName.ReleaseBuffer();

		CString strPath;
		m_lstCurretnUsed.GetItemText(i, 2, strPath.GetBuffer(MAX_PATH), MAX_PATH);
		strPath.ReleaseBuffer();

		CComFunRestry::CreateValue(HKEY_CURRENT_USER, _T("Software\\Microsoft\\VisualStudio\\9.0\\ProjectMRUList"),
			strName, (byte*)(LPCTSTR)strPath, strPath.GetLength() * sizeof(TCHAR), REG_EXPAND_SZ);
	}

	CString strPath;
	GetStoredConfigpath(strPath);
	::DeleteFile(strPath);
	TCHAR strCount[10] = {};
	_itot_s(m_lstStored.GetItemCount(), strCount, 10, 10);
	::WritePrivateProfileString(_T("Globe"), _T("TotalCount"), strCount, strPath);

	for (int i = 0; i < m_lstStored.GetItemCount(); i++)
	{
		TCHAR strIndex[10] = {};
		_itot_s(i, strIndex, 10, 10);

		CString strSolutionPath;
		m_lstStored.GetItemText(i, 1, strSolutionPath.GetBuffer(MAX_PATH), MAX_PATH);
		strSolutionPath.ReleaseBuffer();
		::WritePrivateProfileString(_T("Globe"), strIndex, strSolutionPath, strPath);
	}

	return 0;
}

void CMainDlg::GetStoredConfigpath( CString& strPath )
{
	CComFunPathHelper::ExpandEnvironmentString(
		_T("%appdata%\\Microsoft\\VisualStudio\\9.0\\VS Help Data"), strPath);
	CComFunPathHelper::PathAppend(strPath, _T("SolutionManage.ini"));
}
